<script setup lang="ts">
import { reactive, shallowRef, nextTick, provide, onMounted, computed, ref } from "vue";
import i18n from './common/i18n/index.ts';
import ConnectionVue from "./views/Connection/Index.vue";
import EditConfigurationVue from "./views/Configuration/Index.vue";
import PreferenceVue from "./views/Preference/Index.vue";
import type { ConnectionEvent, ConnectionOptions, Preference, TabItem, CopiedData } from "./common/types.d.ts";
import { TabsInstance, TabPaneName, ElNotification } from "element-plus";
import GlobalVue from "./views/Global.vue";
import DialogVue from "./components/Dialog.vue";
import { Channel, invoke } from "@tauri-apps/api/core";
import dialogTool from "./common/dialogTool.ts";
import { connectionService } from "./common/api.ts";
import TextConverterVue from "./views/Tools/TextConverter.vue";
import AboutVue from "./views/About.vue";
import { open } from '@tauri-apps/plugin-dialog';


const tab = shallowRef<TabsInstance>();
const isDisableAddConnection = ref(false);
const tabContents = shallowRef([]);
const editConfugurationDialog = shallowRef();
const editConfigurationForm = shallowRef();
const preferenceDialog = shallowRef();
const preferenceForm = shallowRef();
const aboutDialog = shallowRef();
const textConverterDialog = shallowRef();

const isDisableBtn = computed(() => {
  return data.activeTab == -1;
})


const copiedData: CopiedData = {
  value: null,
  isCut: false
}

provide("setCopiedData", (value: any, isCut: boolean) => {
  copiedData.value = value;
  copiedData.isCut = isCut;
});

provide("getCopiedData", () => {
  return copiedData;
});

const data = reactive({
  activeTab: -1,
  tabs: [] as TabItem[],
  language: "zh-CN",
  version: "",
  isMaximized: false,
});

const addConnection = (path: string | null) => {
  isDisableAddConnection.value = true;
  connectionService.create(path).then(res => {
    const tab: TabItem = {
      name: res,
      label: "loading...",
      i18nKey: "connection",
      closable: true,
      component: shallowRef(ConnectionVue)
    };
    data.tabs.push(tab);
    nextTick(() => {
      data.activeTab = tab.name;
      setTimeout(() => {
        isDisableAddConnection.value = false;
      }, 250);
    })
  });
}

const openConnection = async () => {
  // 打开文件
  let path = await open({ multiple: false, filters: [] });;
  if (path == null) {
    return;
  }
  addConnection(path);
}

// const onTabChange = (name: TabPaneName): void => {
//   console.log(`tab change to ${name}`)
// }

const onTabRemove = (name: TabPaneName): void => {
  let isSelected = data.activeTab == name;
  for (let i = 0; i < data.tabs.length; i++) {
    if (data.tabs[i].name == name) {
      connectionService.remove(data.tabs[i].name);
      data.tabs.splice(i, 1);
      if (isSelected) {
        const nextTab = data.tabs[i] || data.tabs[i - 1];
        if (nextTab) {
          data.activeTab = nextTab.name;
        }
      }
      break;
    }
  }
}

const onLanguageChanged = (value: "zh-CN" | "en-US") => {
  i18n.global.locale.value = value;
}

const editConfiguration = () => {
  editConfugurationDialog.value.open(i18n.global.t("editConfiguration"));
  nextTick(() => {
    const connection = getConnection();
    if (connection == null) {
      return;
    }
    editConfigurationForm.value.load(data.activeTab);
  });
}

provide("editOptions", editConfiguration);

const closeConfigurationDialog = (configuration: ConnectionOptions | null) => {
  editConfugurationDialog.value.close();
  if (configuration) {
    const connection = getConnection();
    if (connection == null) {
      return;
    }
    connection.setConfiguration(configuration);
  }
}

const openPreference = () => {
  preferenceDialog.value.open(i18n.global.t("preference"));
  nextTick(() => {
    const connection = getConnection();
    if (connection == null) {
      return;
    }
    preferenceForm.value.load(data.activeTab);
  });
}

const closePreferenceDialog = (isHide: boolean, preference: Preference | null) => {
  if (isHide) {
    preferenceDialog.value.close();
  }
  if (preference != null) {
    nextTick(() => {
      const connection = getConnection();
      if (connection == null) {
        return;
      }
      connection.setPreference(preference);
    });
  }
}

document.body.onkeydown = async (evt: KeyboardEvent) => {
  if (dialogTool.isMaskShowed() && evt.key != 'Escape') {
    return;
  }
  const lowerKey = evt.key.toLowerCase();
  if (evt.ctrlKey) {
    if (lowerKey == 's') {
      saveSML(false);
    }
    else if (lowerKey == 'b') {
      const connection = getConnection();
      connection?.getTransactionTree().pasteToPrevious();
    }
    else if (lowerKey == 'c') {
      const connection = getConnection();
      connection?.getTransactionTree().copy();
    }
    else if (lowerKey == 'd') {
      const connection = getConnection();
      connection?.getTransactionTree().duplicate();
    }
    else if (lowerKey == 'e') {
      const connection = getConnection();
      connection?.getTransactionTree().reload();
    }
    else if (lowerKey == 'l') {
      const connection = getConnection();
      connection?.getTransactionTree().replace();
    }
    else if (lowerKey == 'n') {
      const connection = getConnection();
      connection?.getTransactionTree().pasteToNext();
    }
    else if (lowerKey == 'q') {
      const connection = getConnection();
      connection?.getTransactionTree().insertChildItem();
    }
    else if (lowerKey == 'r') {
      const connection = getConnection();
      connection?.getTransactionTree().refresh();
      evt.preventDefault();
    }
    else if (lowerKey == 'v') {
      const connection = getConnection();
      connection?.getTransactionTree().pasteToChild();
    }
  }
  else if (evt.altKey) {
    if (lowerKey == 's') {
      saveSML(true);
    }
  }
  else if (lowerKey == 'f1') {
    const connection = getConnection();
    connection?.getTransactionTree().openProperty();
  }
  else if (lowerKey == 'f2') {
    const connection = getConnection();
    connection?.getTransactionTree().sendPrimaryMessage();
  }
  else if (lowerKey == 'f3') {
    const connection = getConnection();
    connection?.getTransactionTree().insertPreviousItem();
    evt.preventDefault();
  }
  else if (lowerKey == 'f4') {
    const connection = getConnection();
    connection?.getTransactionTree().insertNextItem();
  }
  else if (lowerKey == 'delete') {
    const connection = getConnection();
    connection?.getTransactionTree().deleteNode();
  }
  else if (lowerKey == 'escape') {
    dialogTool.closeCurrentDialog();
  }
  else if (lowerKey == '+' || lowerKey == '=') {
    const connection = getConnection();
    connection?.getTransactionTree().collapse();
  }
  else if (lowerKey == '-') {
    const connection = getConnection();
    connection?.getTransactionTree().expand();
  }
}

const saveSML = async (isSaveAs: boolean) => {
  const connection = getConnection();
  if (connection == null) {
    return;
  }
  connection.saveSML(isSaveAs);
}


const getConnection = (): any | null => {
  let tabIndex = data.tabs.findIndex(m => m.name == data.activeTab);
  if (tabIndex > tabContents.value.length) {
    return null;
  }
  return tabContents.value[tabIndex];
}

const getConnectionById = (id: number): any | null => {
  let tabIndex = data.tabs.findIndex(m => m.name == id);
  if (tabIndex > tabContents.value.length) {
    return null;
  }
  return tabContents.value[tabIndex];
}

provide("setTabLabel", (id: number, label: string) => {
  let tabItem = data.tabs.find(m => m.name == id);
  if (tabItem != null) {
    tabItem.label = label;
  }
});

provide("appOffsetTop", 62);

const globalEvent = new Channel<ConnectionEvent>();
onMounted(() => {
  /// @ts-ignore
  const tWindow = window.__TAURI__.window.getCurrentWindow();
  tWindow.isMaximized().then((res: boolean) => {
    data.isMaximized = res;
  })
  invoke("init", { channel: globalEvent }).then((res: any) => {
    data.version = res.version;
  })
})

globalEvent.onmessage = (message: ConnectionEvent) => {
  const connection = getConnectionById(message.id);
  if (connection == null) {
    return;
  }
  if (message.entity.event == "LogOutput") {
    connection.appendLog(message.entity);
  }
  else if (message.entity.event == "ConnectionStatusChanged") {
    connection.setConnectionStatus(message.entity.current);
  }
  else if (message.entity.event == "ReceivedPrimaryMessage") {
    connection.getMessageTree().appendPrimaryMessage(message.entity.time, message.entity.message);
  }
  else if (message.entity.event == "SendMessage") {
    connection.getMessageTree().appendMessage(message.entity);
  }
}

const appMinimize = () => {
  /// @ts-ignore
  window.__TAURI__.window.getCurrentWindow().minimize();
}

const appMaximize = () => {
  /// @ts-ignore
  window.__TAURI__.window.getCurrentWindow().toggleMaximize();
  data.isMaximized = !data.isMaximized;
}

const appClose = () => {
  /// @ts-ignore
  window.__TAURI__.window.getCurrentWindow().close();
}

const openAbout = () => {
  aboutDialog.value.open(i18n.global.t("about"));
}

const toolClick = (command: string) => {
  if (command == "textConverter") {
    textConverterDialog.value.open("Text Converter");
  }
  else {
    ElNotification({
      title: 'New Feature',
      message: "It hasn't been implemented yet..",
      type: 'info',
    })
  }
}

</script>

<template>
  <GlobalVue>
    <template #body>
      <el-container>
        <el-header class="no-padding app-header" data-tauri-drag-region>
          <div class="app-title" style="float: left;user-select: none;" data-tauri-drag-region> Quic Secs Simultor
            <span>{{ data.version }}</span>
          </div>
          <div style="float:left;margin-left: 20px;">
            <el-link class="app-link" @click="addConnection(null)" :disabled="isDisableAddConnection">{{
              i18n.global.t("addConnection") }}</el-link>
            <el-link class="app-link" @click="openConnection" style="margin-left: 12px;"
              :disabled="isDisableAddConnection">{{
                i18n.global.t("openConnection") }}</el-link>
            <el-link class="app-link" style="margin-left: 12px;" @click="editConfiguration" :disabled="isDisableBtn">{{
              i18n.global.t("connectionConfiguration") }}</el-link>
            <el-link class="app-link" style="margin-left: 12px;" @click="openPreference" :disabled="isDisableBtn">{{
              i18n.global.t("preference") }}</el-link>
            <el-dropdown class="app-link" style="margin:13px 0px 0px 12px;" @command="toolClick">
              <span class="el-dropdown-link">
                {{ i18n.global.t("tools") }}
                <el-icon class="el-icon--right">
                  <arrow-down />
                </el-icon>
              </span>
              <template #dropdown>
                <el-dropdown-menu>
                  <el-dropdown-item command="textConverter">Text Converter</el-dropdown-item>
                  <el-dropdown-item command="autoTester">Auto Tester</el-dropdown-item>
                  <el-dropdown-item command="binaryConverter">Binary Conveter</el-dropdown-item>
                </el-dropdown-menu>
              </template>
            </el-dropdown>
            <el-link class="app-link" style="margin-left: 15px;" @click="openAbout">{{ i18n.global.t("about")
            }}</el-link>
          </div>
          <div style="float:right;margin: 4px 5px 0px 0px;">
            <el-select v-model="data.language" style="width: 76px;float: left;margin-top: 2px;"
              @change="onLanguageChanged">
              <el-option label="中文" value="zh-CN" />
              <el-option label="English" value="en-US" />
            </el-select>
            <div class="title-ctl" style="--hover-color:var(--color-deep-2)" @click="appMinimize">
              <el-icon>
                <Minus />
              </el-icon>
            </div>
            <div class="title-ctl" style="--hover-color:var(--color-deep-2)" @click="appMaximize">
              <el-icon v-if="data.isMaximized">
                <CopyDocument />
              </el-icon>
              <svg v-else viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="14"
                height="14">
                <path fill="#FFFFFF"
                  d="M936.8 87.2V936H87.2V87.2h849.6m4.8-79.2H81.6C40.8 8 8 40.8 8 81.6v860c0 40.8 32.8 73.6 73.6 73.6h860c40.8 0 73.6-32.8 73.6-73.6V82.4c0.8-41.6-32-74.4-73.6-74.4 0.8 0 0 0 0 0z">
                </path>
              </svg>
            </div>
            <div class="title-ctl" style="--hover-color:var(--el-color-error)" @click="appClose">
              <el-icon>
                <Close />
              </el-icon>
            </div>
          </div>
        </el-header>
        <el-main class="no-padding">
          <el-tabs ref="tab" class="app-nav-tab" v-model="data.activeTab" type="card" @tab-remove="onTabRemove">
            <el-tab-pane v-for="tabItem in data.tabs" :key="tabItem.name" :name="tabItem.name"
              :closable="tabItem.closable">
              <template #label>
                <span style="user-select: none;"> {{ tabItem.label }}</span>
              </template>
              <template #default>
                <component ref="tabContents" :is="tabItem.component" :global-id="tabItem.name"></component>
              </template>
            </el-tab-pane>
          </el-tabs>
        </el-main>
      </el-container>
    </template>
  </GlobalVue>
  <DialogVue ref="editConfugurationDialog" :width="'520'" :height="'420'" :is-show-mask="true">
    <EditConfigurationVue ref="editConfigurationForm" @close="closeConfigurationDialog"></EditConfigurationVue>
  </DialogVue>
  <DialogVue ref="preferenceDialog" :width="'800'" :height="'600'" :is-show-mask="true">
    <PreferenceVue ref="preferenceForm" @close="closePreferenceDialog"></PreferenceVue>
  </DialogVue>
  <DialogVue ref="aboutDialog" :width="'400'" :height="'300'" :is-show-mask="true">
    <AboutVue></AboutVue>
  </DialogVue>
  <DialogVue ref="textConverterDialog" :width="'800'" :height="'600'" :is-show-mask="true">
    <TextConverterVue></TextConverterVue>
  </DialogVue>
</template>
